并发基础1(线程进程、Voliate、synchronize锁实现) 您所在的位置:网站首页 voliate 可见性 并发基础1(线程进程、Voliate、synchronize锁实现)

并发基础1(线程进程、Voliate、synchronize锁实现)

2023-09-10 03:51| 来源: 网络整理| 查看: 265

目录

1:java内存模型

1.1:计算机的内存模型

2:Voliate关键字

2.1:voliate不能保证线程安全(可见性分析)

2.2:voliate禁止指令重排

3:java的线程

3.1:线程和进程

3.2:线程的状态

4:线程安全

4.1:synchronize关键字(悲观锁,阻塞同步)

4.2:Cpmpare And Swip(乐观锁,非阻塞同步CAS)

4.3:CAS怎么使用(显式调用和隐式调用)

5:锁优化(synchronize优化)

5.1:自旋和自适应自旋

5.2:锁消除

5.3:锁粗化

5.4:轻量级锁(绝大部分锁在整个周期都不存竞争)

5.5:偏向锁(无竞争的单线程执行,有竞争的时候才会释放锁)

5.6:偏向锁、轻量级锁、重量级锁对比

6: 什么是死锁?如何避免死锁?

6.1:什么是死锁

6.2:如何避免死锁?

1:java内存模型

1.1:计算机的内存模型

在计算机的内存模型中cpu和内存之间的速度存在数量级所以引入了高速缓存,高速缓存会导致到底以哪个处理器的缓存为主,同步到主内存,这个时候有有了缓存一致性协议,来保证缓存一致性。

指令重排:例如一下五行代码,前四行的在计算机cpu的执行顺序不一定是12345,也可以是13245或者34125,但是第五步的顺序不会变,这种指令重排不会影响最后的计算结果。

              int a=1;

              a++;

              int b=5;

              b++;

             int c=a+b;

1.2:java内存模型

java的内存模型屏蔽掉了计算机硬件和操作系统的差异,但是没有限制处理器使用缓存和主内存进行交互,也没有限制编译器在执行过程中的指令重排这类优化措施。

2:Voliate关键字

voliate关键字有两个作用(可见性和禁止指令重排)

1:可见性:保证在多个线程的情况下,线程一把int a的值修改为5的时候,其他线程也能立即知道int a=5,实现的方法是线程1把int a=5,会把a=5的是立马通过缓存同步到主内存,然后其他线程使用a之前会从主内存刷新一次,得到被线程1修改的值为5.

2:有序性:有序性的意思的在本线程内观察,所有操作都是有序的(线程内是串行的),但是在另一个线程观察本线程,所有操作都是无序的(主要是指指令重排现象和工作内存与主内存同步)。voliate和synchronize两个关键字来保证线程操作之间的有序性。

2.1:voliate不能保证线程安全(可见性分析)

预期结果:10个线程同时执行,每一个此线程都把i累加到1000.最后的结果应该是10000.

实际结果:多次运行,大部分结果都不足10000

结论分析:i++,不是原子性操作,线程1把i的值赋值的10,这个时候后线程2根据可见性也得到了10,但是线程1接着执行累加把i的值赋值到250,这个时候线程2依然拿到的值是10是过期数据,入栈++后的值为11,把11同步到了主内存,触发了线程1从主内存同步的得到值为11,这个时候会导致线程一的结果错误。

public class VoliteTest { //voliate关键字保证了此变量在各个线程中是一致的 public static volatile int id=1; public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub Thread[] ths=new Thread[10]; for(int i=0;i1) { Thread.yield(); } System.out.println("========================"); System.out.println("ID的值是:"+id); } //该方法可以通过加锁实现线程安全 public static void add() { for(int i = 0;i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有